<template>
    <el-row :gutter="0">
        <el-col :span="24" style="margin-top:15px;" v-if="path.parameters !== undefined && formData !== undefined">
            <i class="el-icon-s-promotion"></i> <span style="line-height: 28px; font-weight: bold;">Test：</span>
        </el-col>
        <el-col :span="24" v-if="path.parameters !== undefined && formData !== undefined">
            <el-form :ref="path.operationId" :model="formData" :rules="rules" label-width="200px" label-position="left" size="mini" style="margin-top: 10px;">
                <el-form-item v-for="parameter in path.parameters" :key="parameter.name" :label="parameter.name + ' (' + parameter.in + ')'" :prop="parameter.name">
                    <el-input v-if="formatDataType(parameter) === 'string'" v-model="formData[parameter.name]"></el-input>
                    <el-input v-else-if="formatDataType(parameter) === 'byte'" v-model="formData[parameter.name]"></el-input>
                    <el-input v-else-if="formatDataType(parameter) === 'integer'" v-model="formData[parameter.name]"></el-input>
                    <el-input v-else-if="formatDataType(parameter) === 'long'" v-model="formData[parameter.name]"></el-input>
                    <el-input v-else-if="formatDataType(parameter) === 'double'" v-model="formData[parameter.name]"></el-input>
                    <el-input v-else-if="formatDataType(parameter) === 'float'" v-model="formData[parameter.name]"></el-input>
                    <el-date-picker v-else-if="formatDataType(parameter) === 'dateTime'" v-model="formData[parameter.name]" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
                    <el-select v-else-if="formatDataType(parameter) === 'boolean'" v-model="formData[parameter.name]">
                        <el-option :label="'true'" :value="true"></el-option>
                        <el-option :label="'false'" :value="false"></el-option>
                    </el-select>
                    <el-upload v-else-if="formatDataType(parameter) === 'file'" action="/" :http-request="upload" :data="{ name: parameter.name }" :limit="1">
                        <el-button size="small" type="primary">点击上传</el-button>
                    </el-upload>
                    <el-input v-else type="textarea" v-model="formData[parameter.name]" :autosize="{ minRows: 5, maxRows: 10 }"></el-input>
                </el-form-item>
            </el-form>
        </el-col>
        <el-col :span="24">
            <el-button style="width:100%;margin-top:15px;" @click="submit">Try it out!</el-button>
        </el-col>
        <el-col :span="24"
                v-if="showResp"
                v-loading="loading"
                style="margin-top: 15px;"
                element-loading-text="request processing"
                element-loading-spinner="el-icon-loading"
                element-loading-background="rgba(47, 66, 94, 0.8)">
            <el-row>
                <el-col :span="24">
                    <i class="el-icon-info"></i> <span class="response-title">Request URL：</span>
                </el-col>
                <el-col :span="24" class="response-content">
                    <el-input :value="resp.requestUrl"></el-input>
                </el-col>
                <el-col :span="24" style="margin-top: 15px;">
                    <i class="el-icon-info"></i> <span class="response-title">Request Headers：</span>
                </el-col>
                <el-col :span="24" class="response-content">
                    <el-input type="textarea" :value="resp.requestHeaders" :autosize="{ minRows: 1, maxRows: 10 }"></el-input>
                </el-col>
                <el-col :span="24" style="margin-top: 15px;">
                    <i class="el-icon-info"></i> <span class="response-title">Response Body：</span>
                </el-col>
                <el-col :span="24" class="response-content">
                    <el-input type="textarea" :value="resp.responseBody" :autosize="{ minRows: 1, maxRows: 10 }"></el-input>
                </el-col>
                <el-col :span="24" style="margin-top: 15px;">
                    <i class="el-icon-info"></i> <span class="response-title">Response Status：</span>
                </el-col>
                <el-col :span="24" class="response-content">
                    <el-input :value="resp.responseStatus"></el-input>
                </el-col>
                <el-col :span="24" style="margin-top: 15px;">
                    <i class="el-icon-info"></i> <span class="response-title">Response Headers：</span>
                </el-col>
                <el-col :span="24" class="response-content">
                    <el-input type="textarea" :value="resp.responseHeaders" :autosize="{ minRows: 1, maxRows: 10 }"></el-input>
                </el-col>
            </el-row>
        </el-col>
    </el-row>
</template>

<script>
  import axios from 'axios';
  import { mapGetters } from 'vuex';
  export default {
    name: "responses",
    props: ['path'],
    data() {
      const formData = {};
      const rules = {};
      if (this.path.parameters) {
        this.path.parameters.forEach(parameter => {
          formData[parameter.name] = this.getExample(parameter.schema);
          rules[parameter.name] = [{required: parameter.required}]
        });
      }
      return {
        formData,
        rules,
        showResp: false,
        loading: false,
        resp: {
          requestUrl: '',
          requestHeaders: '',
          responseStatus: '',
          responseHeaders: '',
          responseBody: ''
        }
      }
    },
    computed: {
      ...mapGetters([
        'host',
        'basePath'
      ])
    },
    inject: [
      'formatDataType',
      'getExample'
    ],
    methods: {
      upload(obj) {
        this.formData[obj.data.name] = obj.file;
      },
      submit() {
        if (this.$refs[this.path.operationId]) {
          this.$refs[this.path.operationId].validate(valid => {
            if (valid) {
              this.request();
            }
          });
        } else {
          this.request();
        }
      },
      request() {
        this.showResp = true;
        this.loading = true;
        let formData, jsonObj;
        const headers = {}, queries = {};
        let location = this.path.location;

        if (this.path.parameters) {
          this.path.parameters.forEach(parameter => {
            if (parameter.in === 'formData') {
              if (formData === undefined) {
                formData = new FormData();
              }
              formData.append(parameter.name, this.formData[parameter.name]);
            }

            if (parameter.in === 'body') {
              if (jsonObj === undefined) {
                jsonObj = {};
              }
              jsonObj = this.formData[parameter.name];
            }

            if (parameter.in === 'header') {
              headers[parameter.name] = this.formData[parameter.name];
            }

            if (parameter.in === 'query') {
              queries[parameter.name] = this.formData[parameter.name];
            }

            if (parameter.in === 'path') {
              location = location.replace('{' + parameter.name + '}', this.formData[parameter.name]);
            }
          });
        }

        const host = window.location.protocol + '//' + window.location.host;
        const baseURL = host + this.basePath
        const config = {
          url: location,
          method: this.path.method,
          baseURL: baseURL,
          headers: headers,
          params: queries,
        };

        if (formData !== undefined) {
          config.data = formData;
          config.headers['content-type'] = 'multipart/form-data';
        } else if (jsonObj !== undefined) {
          config.data = jsonObj;
          config.headers['content-type'] = 'application/json';
        }
        axios.request(config).then(response => {
          this.resp.requestUrl = host + response.config.url;
          this.resp.requestHeaders = JSON.stringify(response.config.headers, null, 4);
          this.resp.responseBody = JSON.stringify(response.data, null, 4);
          this.resp.responseStatus = response.status;
          this.resp.responseHeaders = JSON.stringify(response.headers, null, 4);
          this.loading = false;
        }).catch((error) => {
          if (error.response) {
            this.resp.requestUrl = host + error.response.config.url;
            this.resp.requestHeaders = JSON.stringify(error.response.config.headers, null, 4);
            this.resp.responseBody = JSON.stringify(error.response.data, null, 4);
            this.resp.responseStatus = error.response.status;
            this.resp.responseHeaders = JSON.stringify(error.response.headers, null, 4);
            this.loading = false;
          }
        });
      }
    }
  }
</script>

<style scoped>
    .response-title {
        line-height: 28px;
        font-weight: bold;
    }

    .response-content {
        margin-top: 10px;
    }
</style>